class ObjectUtil {

    /**
     * @description 深度克隆
     * @param {object} obj 需要深度克隆的对象
     * @returns {*} 克隆后的对象或者原值（不是对象）
     */
    deepClone<T extends any | any[]>(obj: T): T {
        // @ts-ignore
        // 对常见的“非”值，直接返回原来值
        if ([null, undefined, NaN, false].includes(obj)) return obj;
        if (typeof obj !== 'object' && typeof obj !== 'function') {
            // 原始类型直接返回
            return obj;
        }
        const o: T = obj instanceof Array ? [] as any[] : {} as any;
        for (const i in obj) {
            if (obj.hasOwnProperty(i)) {
                // @ts-ignore
                o[i] = typeof obj[i] === 'object' ? this.deepClone(obj[i]) : obj[i];
            }
        }
        return o;
    }

    /**
     * @description JS对象深度合并
     * @param {object} target 需要拷贝的对象
     * @param {object} source 拷贝的来源对象
     * @returns {object|boolean} 深度合并后的对象或者false（入参有不是对象）
     */
    deepMerge(target: Record<string, any> = {}, source: Record<string, any> = {}) {
        target = this.deepClone(target);
        if (typeof target !== 'object' || typeof source !== 'object') return false;
        for (const prop in source) {
            if (!source.hasOwnProperty(prop)) continue;
            if (prop in target) {
                if (typeof target[prop] !== 'object') {
                    target[prop] = source[prop];
                } else if (typeof source[prop] !== 'object') {
                    target[prop] = source[prop];
                } else if (target[prop].concat && source[prop].concat) {
                    target[prop] = target[prop].concat(source[prop]);
                } else {
                    target[prop] = this.deepMerge(target[prop], source[prop]);
                }
            } else {
                target[prop] = source[prop];
            }
        }
        return target;
    }
}

export default new ObjectUtil();
